package view;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

import model.Card;
import model.CardStack;
import model.GameModel;
import model.Suit;

import java.util.*;
import java.util.List;

public class HandComponent extends JComponent{
	private GameModel model;
	private String position;
	private boolean[] selection;
	private TableComponent table;
	
	public HandComponent(final GameModel model, final TableComponent table, String position) {
		this.model = model;
		this.position = position;
		this.table = table;
		
		selection = new boolean[1000];
		for(int n=0; n<1000; n++) selection[n] = false;
		this.addMouseListener(new MouseListener() {

			
			@Override
			public void mouseClicked(MouseEvent arg0) {
				
			}

			@Override
			public void mouseEntered(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseExited(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mousePressed(MouseEvent arg0) 
			{
				if (arg0.getButton() == 1 && arg0.getClickCount() == 1)
				{
					System.out.println("single left click");
					processClick(arg0.getX(), arg0.getY());
				}
				
				else if (arg0.getButton() == 1 && arg0.getClickCount() == 2)
				{
					
					Card card = getCardAt(arg0.getX(), arg0.getY());
					
					if (card != null)
					{
						
						playFromHand(card);
						
						//repaint table somehow
						model.unhighlightAllStacks();
						
						table.repaint();
						
						repaint();
					}
						
					
						
				}
					
			}

			@Override
			public void mouseReleased(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
		});
	}
	public Dimension getPreferredSize() {
		return new Dimension(350, 125);
	}
	public void paint(Graphics tg) {
		Graphics2D g = (Graphics2D)tg;
		
		ArrayList<Card> hand = model.getPlayerHand(position);
		System.out.println(position + " " + hand.size());
		
		sortCardsInHand();
		
		int xpos = 15;
		int ypos = 15;
		for(int i = 0; i<hand.size(); i++) {
			//ypos = selection[i]?5:15;
			Card card = hand.get(i);
			ypos = card.isUp()? 5: 15;
			card.setHandXY(xpos, ypos);
			
			boolean flipped = position=="SOUTH";
			String loaderQuery = flipped?(card.value+card.suit.toString()):"back";
			g.drawImage(ImageLoader.loadImage(loaderQuery), xpos, ypos, null);
			
			xpos+=15;
			ypos+=0;
			
		}
	}
	
	public void addToHand(CardStack stack)
	{
		model.getPlayerHand(position).addAll(stack.getAll());
		
	}
	
	/**
	 * add card from hand to stack on table
	 * @param card
	 * @param tableStack
	 */
	public void playFromHand(Card card)
	{
		card.setHandXY(-1,-1);
	
		CardStack tableStack;
		
		if (model.getTableCards().size() > 0)
		{
			tableStack = model.getTableCards().get(0);
			tableStack.push(card);
			int index = model.getPlayerHand(position).indexOf(card);
			model.getPlayerHand(position).remove(card);
			selection[index] = !selection[index];
			
		}
			
		else
		{
			CardStack s = new CardStack(225, 225);
			s.push(card);
			model.getPlayerHand(position).remove(card);
			model.getTableCards().add(s);
			
		}
		
		
	}
	
	private void processClick(int x, int y) {
/*		if(y>20&&y<80&&x>15&&x<115) {
			int index = (x-15)/15;
			System.out.println(x+" "+y+" "+index);
			selection[index]=!selection[index];
			repaint();
		}*/
		
		System.out.println(x + " " + y + " ");
		Card card = getCardAt(x,y);
		if (card != null)
		{
			System.out.println("found card");
			card.toggleUp();
			repaint();
		}
		
	}
	
	/**
	 * Finds the card that is painted at the given location. 
	 * Currently the algorithm is just to brute force search over all stacks on the table.
	 * May need to improve this algorithm for better performance.
	 */
	public Card getCardAt(int x, int y) {
		
		
		//System.out.println("cards in hand " + model.getPlayerHand(position).size()); 
		for (int i = model.getPlayerHand(position).size() -1; i >=0; i--)
		{
			Card c = model.getPlayerHand(position).get(i);
			if(x < c.getHandX() ||
					x > c.getHandX() + ImageLoader.IMAGE_WIDTH 
					||	y < c.getHandY() 
					||	y > c.getHandY() + ImageLoader.IMAGE_HEIGHT)
				continue;
			
			return c;
		}

		return null;
	}
	
	/**
	 * first order by suit
	 * then use insertion sort
	 */
	public void sortCardsInHand()
	{
		ArrayList<Card> cards = model.getPlayerHand(position);
		
		ArrayList<Card> clubs = new ArrayList<Card>();
		ArrayList<Card> diamonds = new ArrayList<Card>();
		ArrayList<Card> hearts = new ArrayList<Card>();
		ArrayList<Card> spades = new ArrayList<Card>();
		
		for (int i = 0; i < cards.size(); i++)
		{
			Card c = cards.get(i);
			if (c.suit == Suit.CLUB)
				clubs.add(c);
			else if (c.suit == Suit.DIAMOND)
				diamonds.add(c);
			else if (c.suit == Suit.HEART)
				hearts.add(c);
			else if (c.suit == Suit.SPADE)
				spades.add(c);
			else if (c.suit == Suit.JOKER)
				continue;
				
		}
		
		clubs = insertionSort(clubs);
		diamonds = insertionSort(diamonds);
		hearts = insertionSort(hearts);
		spades = insertionSort(spades);
		
		cards.clear();
		
		cards.addAll(clubs);
		cards.addAll(diamonds);
		cards.addAll(hearts);
		cards.addAll(spades);
		
	}
	
	//TODO doesn't completely work...
	private ArrayList<Card> insertionSort(List<Card> A)
	{

		ArrayList<Card> B = new ArrayList<Card>();
		
		for (int i = 0; i < A.size(); i++)
		{
			
			Card a = A.get(i);
			int j;
			for (j = 0; j < B.size(); j++)
			{
				Card b = B.get(j);
				if (a.value < b.value)
				{
					break;
				}
			}
			B.add(j, a);
		
		}
		
		return B;
	}

	
	

}
